package com.example.demo.Controller;

import com.example.demo.model.People;
import com.example.demo.model.User;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.UUID;

/**
 * spring mvc 将视图(展示给用户的页面)给用户
 */

//@RestController =  @ResponseBody + @Controller
//@Controller   //项目运行的时候(在spring启动的时候)加载这个类并注册 ->控制器
//@ResponseBody   // 当前类返回的是非静态页面 可以修饰在类上也可以修饰在方法上 告诉他返回的是数据(响应正文body),不是将页面返回
@RestController
@RequestMapping("/web")//当使用 /web 路由就能访问到当前类 ->二级目录
public class WebController {
    /**
     * 不加ResponseBody ,默认返回的就是视图(页面)
     */
    /**
     * 实现用户和程序建立链接
     * 1.@RequestMapping  -->支持所有使用类型的接口访问(包含Get,Post....)
     * 2.@PostMapping  --->只支持post请求
     * 3.@GetMapping   --->只支持get请求
     * 以上注解要配合RestController / Controller  一起使用
     * @return
     */
    @RequestMapping("/index12")//当使用 /web/hi 路由就能访问到当前类
    public Object index() {
        return "/index.html";// 没找到视图,没找到就会报404
    }

    @RequestMapping(value = "/springmvctest",method = RequestMethod.POST)
    public Object test1(){
        return "spring mvc!!!";
    }

    @PostMapping("/springmvctest2")//---->只支持Post方法
    public Object test2(){
        return "spring mvc~~~";
    }

    @GetMapping("/springmvctest3")//---->只支持Get方法
    public Object test3(){
        return "spring mvc~~~";
    }

    /**
     * 前端给后端发起请求的方式有两种
     * 1. ajax ->JSON对象给后端,一个参数或者几个参数给后端
     * 2.form表单 ->
     * 后端要接收前端的参数
     * 1. 参数
     * 单个参数,多个参数,对象,表单
     * 参数命名 前端必须传某个参数
     * 2.JSON对象
     * 怎么接收JSON对象
     * 3.url传参
     * 4.上传文件->注册上传头像/音乐
     * 5.cookie 和 session
     */

    //2.1获取单个参数--> servlet : req.getParameter()
    // 默认的参数 HttpServletRequest HttpServletResponse
    //通过Servlet中的request中获取参数
    //在springmvc默认内置隐藏了两个参数 HttpServletRequest HttpServletResponse
    @GetMapping("/testdemo1")
    public Object testDemo1(HttpServletRequest req) {
         return "Hi" + req.getParameter("name");
    }

    /**
     * spring mvc 主要获取参数的方式
     * 获取到单个参数,从前端拿到name的这个参数
     * 前端参数和后端参数必须匹配的时候才能获取到,参数名必须相同,一一对应
     * @param age
     * @return
     */

    @GetMapping("/testdemo2")
    public Object testDemo2(Integer age) {
        return "age : " + age + "~~~";
    }

    /**
     * 获取多个参数->两个及以上
     * 参数的顺序无所谓 只看key值是否一样,去前端匹配参数
     * springMVC 只会看参数的名称,不会关心参数的顺序
     * @param name
     * @param age
     * @return
     */

    @GetMapping("/testdemo3")
    public Object testDemo3(String name,int age) {
        //此时已经得到了前端传来的值了
        //执行业务操作...
        return "姓名 : " + name + " 年龄 : " + age;
    }

    /**
     * 传递的参数如果过多,比如成百上千 无法维护
     * 就需要给他封装成对象
     * 接收普通的对象 就是普通的对象 不是JSON
     */
     @GetMapping("/testdemo4")
     public Object testDemo4(People people){
         return people;
     }

    /**
     * 1. url传参
     * 2. ajax传参->前后端分离使用最多的
     * 3. form表单传参
     */

    /**
     * 获取form表单中的参数
     * @param name
     * @param password
     * @return
     */

     @GetMapping("/testdemo5")
     public Object testDemo5(String name ,Integer password){
         return "<h1>用户名 : name " + name + ", 密码 : password  : " +password +" </h1>";
     }

    /**
     * 如果form表单参数过多,后端这边可以封装成一个对象
     * @param user
     * @return
     */

     @GetMapping("/testdemo6")
     public Object testDemo6(User user) {
        return user.toString();
     }

    @RequestMapping("/test_demo7")
    public HashMap<String,Object> testDemo7(@RequestBody String name , Integer password){
        HashMap<String,Object> map = new HashMap<>();
        map.put("name",name);
        map.put("password",password);
        return map;
    }

    /**
     * 从body中获取 -> @RequestBody
     * 得到用户传递的JSON对象
     * @param user
     * @return
     */
    @RequestMapping("/test_demo8")
    public HashMap<String,Object> testDemo8(@RequestBody User user){
        HashMap<String,Object> map = new HashMap<>();
        map.put("name",user.getName());
        map.put("password",user.getPassword());
        return map;
    }

    /**
     * @RequestPart("myFile")MultipartFile file 拿到文件 接下来要保存文件(保存到服务端的电脑上)
     * @param name
     * @param file
     * @return
     */
    @RequestMapping("/test_demo9")
    public Object testDemo9(String name, @RequestPart("myFile")MultipartFile file) throws IOException {
        //拼接动态路径
        // 获取⽂件后缀名
        String fileName = file.getOriginalFilename().substring
                (file.getOriginalFilename().lastIndexOf("."));
        // ⽂件保存地址
        String filePath = ClassUtils.getDefaultClassLoader().getResource("static").getPath()
                + "/" + UUID.randomUUID() + fileName;
        //保存文件->保存到服务端
        file.transferTo(new File(filePath));//写文件名直接保存到当前根目录上->绝对地址
        return "ok";
    }

    /**
     * 获取 cookie ,session ,header 的方法
     */

    /**
     * 获取前端的cookie值
     * 1.Servlet获取方式->一次性获取所有的Cookie
     */
    @RequestMapping("/get_cookie1")
    public Object getCookie1(HttpServletRequest req,HttpServletResponse resp) {
        //获取参数
        String name = req.getParameter("name");
        //获取cookie
        Cookie[] cookies = req.getCookies();
        //获取header
        String header = req.getHeader("User-Agent");
        return null;
    }
    /**
     * SpringMVC 获取cookie的方式->使用注解->获取到一个Cookie
     * @CookieValue("cookie的名字") String cookieName 赋值给cookieName这个变量
     */
    @RequestMapping("/get_cookie2")//@CookieValue(cookie的名字) 赋值给的变量
    public Object getCookie2(@CookieValue("cookieName") String cookieName,
                             @CookieValue("cookie1") String cookie1,
                             @CookieValue("cookie2") String cookie2) {
        return "cookieName : " + cookieName + " cookie1 : " + cookie1
                + " cookie2 : " + cookie2;
    }
    /**
     * Servlet 获取Session的方式
     */
    @RequestMapping("/get_session1")
    public Object getSession1(HttpServletRequest req,HttpServletResponse resp) {
        HttpSession session = req.getSession(true);//有返回session,没有就会创建
        //存储Session
        if(session!=null){
            session.setAttribute("name","sfx");
        }
        return " ";
    }
    /**
     * Servlet 获取session的方式
     */
    @RequestMapping("/get_session2")
    public Object getSession2(HttpServletRequest req,HttpServletResponse resp) {
        HttpSession session = req.getSession(false);//没有返回null,不会新创建
        String userName = null;
        if(session!=null&&session.getAttribute("name")!=null) {
            userName = (String) session.getAttribute("name");
        }
        return "userName :" + userName;
    }
    /**
     * 设置/存储session
     */
    @RequestMapping("/set_session3")
    public Object setSession3(HttpServletRequest req,HttpServletResponse resp) {
        HttpSession session = req.getSession(true);//有返回session,没有就会创建
        //存储Session
        if(session!=null){
            session.setAttribute("name","sfx");
        }
        return "session 存储成功";
    }

    /**
     * SpringMVC 获取session的方式->不设置required
     */
    @RequestMapping("/get_session4")
    public Object getSession4(@SessionAttribute("name") String name) {
         return "name : " + name;
    }

    /**
     * SpringMVC 获取session的方式 ->设置required
     * required 默认是true 没有session的话就会报错
     * required 设置false 没有session的话就返回null
     */
    @RequestMapping("/get_session5")
    public Object getSession5(@SessionAttribute(value = "name",required = false) String name) {
        return "name : " + name;
    }
    /**
     * 上面讲了6种获取前端参数的方式
     */

    /**
     * Servlet获取header
     */
    @RequestMapping("/get_header1")
    public Object getHeader1(HttpServletRequest req) {
        String userAgent = req.getHeader("User-Agent");
        return "userAgent : " + userAgent;
    }

    /**
     * SpringMVC获取header
     */
    @RequestMapping("/getheader2")
    public Object getHeader2(@RequestHeader("User-Agent") String userAgent,
                             @RequestHeader("Accept-Language") String language) {
        return "userAgent : " + userAgent + " language : " + language;
    }
    /**
     * 参数重命名
     * 利用@RequestParam(前端传来的) 自己重新命名的名字
     * 前端只有传t才能响应(只能识别t参数,将t参数的值重命名为time),传time报错
     * required = false 拿不到前端传的参数 返回null (当前参数选传)
     * required = true  拿不到前端传的参数 则报错  (当前参数必传)
     * 参数重命名后,只认一个
     */
    @RequestMapping("/getparam")
    public Object getparam(@RequestParam(value = "t",required = false) String time) {
        return "time : " + time;
    }

    /**
     * 读取URL里面的参数,在路由路径里面通过层级传参数
     * 如 localhost:8080/geturl/name=zhangsan/password=123456
     * 从URL中获取参数 不是 ? 而是获取/后面的参数->动态的参数
     * 要加注解@PathVariable
     */
    @RequestMapping("/geturl/{name}/{password}")
    public Object geturl(@PathVariable("name") String userName,//重命名
                         @PathVariable String password) {//没有重命名
        return "name : " + userName + " password : " + password;
    }

    /**
     * 1.将结果返回给前端 -> return
     * 2.请求转发 和 请求重定向
     */




}